import { Component, Ref, VNode } from "vue"
import type { Cell, Edge, Graph,Model } from "@antv/x6"
import Main from "./main"

export namespace IPackAntvX6 {
    export interface Props {
        main:Main
    }


    // export interface AdapterConfig {
    //     option?:Graph.Options
    //     status?:Record<string,boolean|string|number>
    //     metadata?:Map<string,CellMetadata> | ((e:Adapter) => Promise<Map<string,CellMetadata>>)
    //     nodelist?:NodelistItem[]
    //     nodelistVNode?:VNode|Component
    //     drawerVNode?:VNode|Component
    //     getContextmenuList?:(arg:{cell?:Cell,e:Event,adapter:Adapter}) => Promise<VNode[]|Component[]>
    //     api?:API
    //     mode?:"prod" | "dev"
    // }

    // export interface Config {
    //     option?:Graph.Options
    //     status?:Record<string,boolean|string|number>
    //     metadata?:Map<string,CellMetadata> | ((e:Adapter) => Promise<Map<string,CellMetadata>>)
    //     nodelist?:NodelistItem[]
    //     nodelistVNode?:VNode|Component
    //     drawerVNode?:VNode|Component
    //     getContextmenuList?:(arg:{cell?:Cell,e:Event,adapter:Adapter}) => Promise<VNode[]|Component[]>
    //     api?:API
    //     mode?:"prod" | "dev"
    // }

    export type API = {get:(url:string,options?:any) => Promise<any>,post:(url:string,data?:any,options?:any) => Promise<any>,delete:(url:string,data?:any,options?:any) => Promise<any>,put:(url:string,data?:any,options?:any) => Promise<any>}

    export interface CellMetadata{

    }

    export interface CompProps {
        main:Main
    }

    export interface NodelistItem extends Record<string,any> {
        label:string
        icon?:VNode|Component|string
        desc?:string
        name?:string,
        class?:string,
        children?:NodelistItem[]
        
    }


    export interface BoxEl {
        el?:HTMLElement
        close:() => void
    }

    export interface DialogEl extends BoxEl {
        submit:(call?: (e?: Event) => Promise<boolean | void>) => Promise<any>
        cancel:(call?: (e?: Event) => Promise<boolean | void>) => Promise<any>
        finish:(call?: (e?: Event) => Promise<boolean | void>) => Promise<any>
        handleSubmit:(e?:any) => void
        handleCancel:(e?:any) => void
    }

    export interface ProverEl extends BoxEl {
        open:() => void
    }

    export interface DrawerEl extends BoxEl {
        open:() => void
    }

    export interface X6 {
        
        init?: (options: Graph.Options) => Graph
        ElBox?:HTMLDivElement
        ElRoot?:HTMLDivElement
        graph?:Graph
        //
        options:Graph.Options
        //
        NODE_MD:any
        EDGE_MD:any
        DICT_EDGES:any[]
        //
        config:GraphConfig
        //
        mounted:(options:Graph.Options) => Graph
        registerEdge:(name:string,md:Edge.Metadata,force:boolean) => void
        registerNode:(name:string,md:Edge.Metadata,force:boolean) => void

    }

    export interface X6Graph extends Graph {
        isInit:boolean
        initTime:Ref<number>
        isFull:Ref<boolean>
        mode:Ref<'dev'|'prod'> // 当前画布的模式
        loading:Ref<boolean>
        animate:Ref<boolean>
        config:{
            x: number;
            y: number;
            scale: number;
            edge: number;
            move: boolean;
            panning: boolean;
            port: boolean;
            interacting: boolean;
            nodelist: boolean;
            menu: boolean;
        }, // 常用表单属性集合
        //
        containerEl:HTMLDivElement; // 画布容器
        boxEl:HTMLDivElement // 画布父容器
        rootEl:HTMLDivElement // 画布组件根容器
        //
        toggleFull:() => X6Graph
        BG:Ref<string>
        setBG:(c:string) => X6Graph
        fullBG:Ref<string>
        setFullBG:(c:string) => X6Graph
        // 启用动画 500 毫秒后自动关闭
        startAnimate:() => X6Graph
        //
        scaleTo:(s?:number | "+" | "-" | "=") => X6Graph
        //
        registerNode:(name:string,md:any,force?:boolean) => X6Graph
        registerEdge:(name:string,md:any,force?:boolean) => X6Graph
        //
        resetConfig:(config:any) => X6Graph
        recoverConfig:() => X6Graph
        saveConfig:() => X6Graph
        resetOptions:(ops:Graph.Options) => X6Graph // 使用 config 数据 重置画布 OPTIONS
        //
        mounted:(box:HTMLDivElement,root:HTMLDivElement) => X6Graph; // vue 模板 mounted 时的 call
        onMounted:(callback:(graph:Graph) => void) => X6Graph; // 可以添加自定义的函数到 初始化的过程
        init:(option?:Graph.Options) => X6Graph; // 初始化画布实例 可以自定义画布 options
        destory:() => X6Graph // 销毁画布以及画布容器下的所有元素

        refresh:(data:Model.FromJSONData,options?:Model.FromJSONOptions) => X6Graph // 刷新画布
        change:(data:Model.FromJSONData) => X6Graph // 变化刷新 新增或者移除节点时获取到了全部的元素数据可以使用
        reset:(data?:Model.FromJSONData) => X6Graph // 重置画布 重新构造 options 并刷新画布

        search:(v:string|((cell:Cell) => boolean),names?:string[]) => Cell[]

        layout:(f:(m:any) => any[]) => X6Graph // 布局

        save:() => any // 保存当前画布数据

        load:(data:any) => X6Graph

        setViewStyle:(cell:Cell,style?:string) => X6Graph
        // search:(s:string,names:string[]) => Cell[]
    
    }

    export type LayoutNames = 'self'|"grid"|"circular"|"dagre"|"ellipse";

    export interface GraphConfig { 
        x: number, // 画布当前坐标
        y: number, // 
        scale: number, // 画布缩放系数
        // scaleSpeed: number, // 画布缩放速度
        edge: number, // 边的线形
        // router:"normal"|"manhattan"|"metro"|"normal", // 边的路由
        // connector:"normal"|"rounded"|"smooth", 
        // layout: LayoutNames, 
        map: boolean, 
        // full: boolean, 
        // edit: boolean, 
        move: boolean,
        // connect:boolean, 
        // add: boolean, 
        // remove: boolean, 
        panning: boolean, 
        port: boolean, 
        interacting: boolean, 
        // contextmenu: boolean, 
        // nodelist: boolean, 
        // menu: boolean, 
        // position: boolean, 
        // loading: boolean 
    }

    export interface ToolbarProps {
        enabled: Ref<boolean>
    minimap: Ref<boolean>
    menu: Ref<boolean>
    nodelist: Ref<boolean>
    drawer: Ref<boolean>
    contextmenu: Ref<boolean>
    mousepos: Ref<boolean>
    isFold: Ref<boolean>
    module: {
        menu: boolean;
        nodelist: boolean;
        zoom: boolean;
        scale: boolean;
        full: boolean;
        edge: boolean;
        layout: boolean;
        map: boolean;
        switch: boolean;
        search: boolean;
        import: boolean;
        export: boolean;
    }
    main: Main
    }

    export interface MenuProps {
        title:(VNode|Component|string)[]
        operates:(VNode|Component)[]
        main:Main
    }

    export interface MinimapProps {
        time:Ref<number>
        visible:Ref<boolean>
        init:(box:HTMLDivElement) => void
    }

    export interface DrawerProps {
        maxSize?:string
        minSize?:string
        size?:number
        visible:Ref<boolean>
        vnode:Ref<VNode|undefined>
    }

    export interface ContextmenuProps {
        visible:Ref<boolean>
        posStyle:Ref<string>
        vnode:Ref<VNode|undefined>
        close:() => void
    }

    export interface NodelistProps {
        main:Main
        list:IPackAntvX6.NodelistItem[]
    }
}